package com.smart.common.config.satoken;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.digest.DigestUtil;
import com.smart.common.entities.ajax.AjaxResult;
import com.smart.common.entities.constant.SmartConstant;
import com.smart.utils.ResponseUtil;
import lombok.extern.log4j.Log4j2;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;


/**
 * 请求拦截器 移动端
 *
 * @author Administrator
 */
@Log4j2
public class WapInterceptor implements HandlerInterceptor {


    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        String requestURI = request.getRequestURI().replace("//","/");
        //  没有开启验证 不是移动端的接口 直接方行
        if (!StrUtil.startWith(requestURI, "/api/" + SmartConstant.CHECK_HEADER_PKG + "/app")) {
            return true;
        }
        //设备终端
        String client = request.getHeader("x-api-client");
        //随机字符串
        String nonce = request.getHeader("x-api-nonce");
        //设备IMEI
        String imei = request.getHeader("x-api-imei");
        //设备时间戳
        String timestamp = request.getHeader("x-api-timestamp");

        //请求签名
        String sign = request.getHeader("x-api-sign");
        if (!StrUtil.isAllNotBlank(client, nonce, imei, sign, timestamp)) {
            AjaxResult<Object> fail = AjaxResult.fail(5000, "请求HEADER验证失败:非法的数据请求");
            ResponseUtil.out(response, fail);
            return false;
        }
        if (StrUtil.length(nonce) > 32) {
            AjaxResult<Object> fail = AjaxResult.fail(5000, "请求HEADER验证失败:签名随机字符串格式错误");
            ResponseUtil.out(response, fail);
            return false;
        }

        if (!StrUtil.isNumeric(timestamp) || StrUtil.length(timestamp) != 10) {
            AjaxResult<Object> fail = AjaxResult.fail(5000, "请求HEADER验证失败:错误的时间戳格式");
            ResponseUtil.out(response, fail);
            return false;
        }
        long timestampLong = Long.parseLong(timestamp);
        if (Math.abs(DateUtil.currentSeconds() - timestampLong) > 300L) {
            AjaxResult<Object> fail = AjaxResult.fail(5000, "请求HEADER验证失败:请求的设备时间异常 设备上报时间戳:" + timestamp);
            ResponseUtil.out(response, fail);
            return false;
        }
        //开始验证签名
        String format = String.format("SMART-%s-%s-%s-%s", client, nonce, imei, timestamp);
        String rightSign = DigestUtil.md5Hex(format).toUpperCase();
        if (!StrUtil.equals(rightSign, sign)) {
            AjaxResult<Object> fail = AjaxResult.fail(5000, "请求HEADER验证失败:请求签名错误");
            ResponseUtil.out(response, fail);
            return false;
        }

        //缓存到线程中客户端信息
        Map<String, String> clientDict = Map.of("client", client, "imei", imei);
        LocalContextClient.set(clientDict);
        return true;

    }

}
